<template>
  <div class="metaverse-page">
    <div class="page-header">
      <h1 class="title">二手车元宇宙</h1>
      <p class="subtitle">体验未来二手车交易方式</p>
    </div>
    
    <div class="metaverse-container" ref="metaverseContainer">
      <div v-if="loading" class="loading-overlay">
        <div class="icon-container">
          <i class="el-icon-loading"></i>
        </div>
        <p>正在加载3D元宇宙场景...</p>
      </div>

      <div v-if="!loading" class="controls-info">
        <p>操作方法:</p>
        <ul>
          <li>WASD - 移动人物(相对于当前视角的前后左右)</li>
          <li>鼠标拖动 - 旋转视角</li>
          <li>鼠标滚轮 - 缩放视角</li>
          <li>点击汽车 - 查看详情</li>
        </ul>
      </div>
      
      <div v-if="showCarInfo" class="car-info-panel">
        <div class="car-info-header">
          <h3>{{ carInfo.name }}</h3>
          <span class="close-btn" @click="closeCarInfo">×</span>
        </div>
        <div class="car-info-body">
          <div class="car-specs">
            <div class="spec-item">
              <span class="label">价格:</span>
              <span class="value">{{ carInfo.price }}</span>
            </div>
            <div class="spec-item">
              <span class="label">车龄:</span>
              <span class="value">{{ carInfo.age }}</span>
            </div>
            <div class="spec-item">
              <span class="label">里程:</span>
              <span class="value">{{ carInfo.mileage }}</span>
            </div>
            <div class="spec-item">
              <span class="label">排量:</span>
              <span class="value">{{ carInfo.engine }}</span>
            </div>
          </div>
          <div class="car-description">
            <p>{{ carInfo.description }}</p>
          </div>
          <div class="car-actions">
            <el-button type="primary" size="small" @click="handleTest">试驾体验</el-button>
            <el-button type="success" size="small" @click="handleBook">预约看车</el-button>
          </div>
        </div>
      </div>
      
      <div v-if="showTooltip" class="interaction-tooltip" :style="tooltipStyle">
        {{ tooltipText }}
      </div>
      
      <div class="mini-map">
        <div class="map-container">
          <div class="player-marker" :style="playerMarkerStyle"></div>
        </div>
      </div>
      
      <div class="digital-human-feature">
        <div class="feature-icon">
          <i class="el-icon-user"></i>
        </div>
        <div class="feature-content">
          <h3>数字人功能</h3>
          <p>AI数字人助手功能正在开发中...</p>
          <div class="development-badge">开发中</div>
        </div>
      </div>
      
      <canvas ref="threeCanvas" class="three-canvas"></canvas>
    </div>
    
    <div class="return-home">
      <el-button type="primary" @click="goBack">返回首页</el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { useRouter } from 'vue-router'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import * as CANNON from 'cannon-es' // 引入 cannon-es
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js' // 引入 GLTFLoader
// 暂时注释掉未使用的模块
// import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'

const router = useRouter()
const threeCanvas = ref(null)
const metaverseContainer = ref(null)
const loading = ref(true)

// 车辆信息面板
const showCarInfo = ref(false)
const carInfo = ref({
  name: '宝马 3系 2020款',
  price: '￥268,000',
  age: '3年',
  mileage: '35,000公里',
  engine: '2.0T',
  description: '这款宝马3系车况极佳，原厂保养记录完整，一手车主，无事故，无泡水，全车原漆。内饰干净整洁，发动机工作平稳，变速箱换挡顺畅。'
})

// 交互提示
const showTooltip = ref(false)
const tooltipText = ref('')
const tooltipStyle = ref({
  left: '0px',
  top: '0px'
})

// 小地图玩家标记样式
const playerMarkerStyle = computed(() => {
  if (!characterControls) return { left: '50%', top: '50%' }
  
  // 将3D世界坐标映射到小地图上
  const mapSize = 100 // 对应3D世界的尺寸
  const mapContainerSize = 120 // 小地图容器的像素尺寸
  
  // 计算位置百分比
  const xPercent = ((characterControls.model.position.x + mapSize/2) / mapSize) * 100
  const yPercent = ((characterControls.model.position.z + mapSize/2) / mapSize) * 100
  
  // 计算旋转角度
  const rotation = characterControls.model.rotation.y * (180 / Math.PI) + 180
  
  return {
    left: `${xPercent}%`,
    top: `${yPercent}%`,
    transform: `translate(-50%, -50%) rotate(${rotation}deg)`
  }
})

// three.js相关变量
let scene, camera, renderer, controls, clock
let character, mixer, animationsMap = {}, currentAction
const keysPressed = {}
let characterControls
let cars = [] // 存储场景中的汽车对象
let carModelAsset = null // 用于存储预加载的汽车模型
let raycaster, mouse // 用于射线检测

// 物理引擎相关变量
let world
let groundBody, characterBody
const timeStep = 1 / 60 // 物理模拟步长
const jumpVelocity = 5 // 跳跃时的初始速度
let canJump = false // 是否可以跳跃 (接触地面时为true)

// 关闭车辆信息面板
const closeCarInfo = () => {
  showCarInfo.value = false
}

// 处理试驾
const handleTest = () => {
  alert('试驾功能即将上线，敬请期待！')
}

// 处理预约
const handleBook = () => {
  alert('预约成功！客服将会联系您安排看车时间。')
  closeCarInfo()
}

// 更新射线检测
const updateRaycaster = () => {
  // 只有在有鼠标位置的情况下才进行检测
  if (!raycaster || !mouse) return
  
  // 更新射线
  raycaster.setFromCamera(mouse, camera)
  
  // 检测与汽车的交互
  const intersects = raycaster.intersectObjects(scene.children, true)
  
  let isOverCar = false
  let carModel = null
  
  // 检查是否有交互的汽车
  for (let i = 0; i < intersects.length; i++) {
    // 向上查找父级，看是否是汽车模型
    let parent = intersects[i].object
    while (parent && parent.userData.type !== 'car') {
      parent = parent.parent
    }
    
    if (parent && parent.userData.type === 'car') {
      isOverCar = true
      carModel = parent
      break
    }
  }
  
  // 如果鼠标悬停在汽车上，显示提示
  if (isOverCar && carModel) {
    showTooltip.value = true
    tooltipText.value = `点击查看: ${carModel.userData.name}`
    
    // 计算提示框位置
    const vector = new THREE.Vector3()
    vector.setFromMatrixPosition(carModel.matrixWorld)
    vector.project(camera)
    
    const x = (vector.x + 1) / 2 * metaverseContainer.value.clientWidth
    const y = (-vector.y + 1) / 2 * metaverseContainer.value.clientHeight
    
    tooltipStyle.value = {
      left: `${x}px`,
      top: `${y - 50}px`
    }
  } else {
    showTooltip.value = false
  }
}

// 鼠标点击事件
const onMouseClick = (event) => {
  // 计算鼠标在归一化设备坐标中的位置
  const rect = threeCanvas.value.getBoundingClientRect()
  mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
  mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
  
  // 更新射线
  raycaster.setFromCamera(mouse, camera)
  
  // 检测与汽车的交互
  const intersects = raycaster.intersectObjects(scene.children, true)
  
  for (let i = 0; i < intersects.length; i++) {
    // 向上查找父级，看是否是汽车模型
    let parent = intersects[i].object
    while (parent && parent.userData.type !== 'car') {
      parent = parent.parent
    }
    
    if (parent && parent.userData.type === 'car') {
      // 显示车辆信息
      carInfo.value = parent.userData.info
      showCarInfo.value = true
      return
    }
  }
}

// 鼠标移动事件
const onMouseMove = (event) => {
  // 计算鼠标在归一化设备坐标中的位置
  const rect = threeCanvas.value.getBoundingClientRect()
  mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
  mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
}

// 更新角色位置和动画 (物理引擎版本)
const updateCharacter = (deltaTime) => {
  if (!characterControls || !characterBody) return
  
  // 强制设置可以跳跃状态为 true，绕过碰撞检测
  canJump = true;

  // 根据按键计算移动方向
  const directionPressed = new THREE.Vector3()
  // 修正移动方向 - 前后左右
  if (keysPressed['w'] || keysPressed['arrowup']) directionPressed.z = 1  // 前
  if (keysPressed['s'] || keysPressed['arrowdown']) directionPressed.z = -1   // 后
  if (keysPressed['a'] || keysPressed['arrowleft']) directionPressed.x = 1  // 左 
  if (keysPressed['d'] || keysPressed['arrowright']) directionPressed.x = -1   // 右


  // 计算相对于相机的移动方向
  const moveDirection = new THREE.Vector3()
  let isMoving = false
  if (directionPressed.length() > 0) {
    isMoving = true
    directionPressed.normalize()
    
    // 获取相机前向方向，忽略Y轴
    const cameraDirection = new THREE.Vector3()
    camera.getWorldDirection(cameraDirection)
    cameraDirection.y = 0
    cameraDirection.normalize()
    
    // 获取相机右向量
    const cameraRight = new THREE.Vector3()
    cameraRight.crossVectors(new THREE.Vector3(0, 1, 0), cameraDirection).normalize()

    // 根据按键和相机方向计算实际移动方向
    moveDirection.add(cameraDirection.clone().multiplyScalar(directionPressed.z))
    moveDirection.add(cameraRight.clone().multiplyScalar(directionPressed.x))
    moveDirection.normalize()

    // 更新角色朝向 - 修复角色朝向，使正面朝向移动方向
    if (moveDirection.length() > 0.1) {
      // 添加PI旋转180度，让角色面向前进方向
      const targetAngle = Math.atan2(moveDirection.x, moveDirection.z) + Math.PI
      const targetQuaternion = new THREE.Quaternion()
      targetQuaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), targetAngle)
      characterControls.model.quaternion.slerp(targetQuaternion, 0.2) // 平滑转向
    }
  }

  // 提高移动速度
  const moveSpeed = characterControls.speed * 2.5 // 从 1.8 提高到 2.5

  // 直接设置物理位置，完全绕过物理引擎的限制
  if (isMoving) {
    // 直接更新位置，不受物理引擎限制
    characterBody.position.x += moveDirection.x * moveSpeed * deltaTime;
    characterBody.position.z += moveDirection.z * moveSpeed * deltaTime;
    // 仅保留Y轴的物理计算以保持重力效果
    characterBody.velocity.x = 0;
    characterBody.velocity.z = 0;
  }

  // 更新动画状态
  const idleAction = animationsMap.get('Idle') || animationsMap.get('idle')
  const walkAction = animationsMap.get('Walking') || animationsMap.get('Walk') || animationsMap.get('walk') || animationsMap.get('run')
  const jumpAction = animationsMap.get('Jump') || animationsMap.get('jump')

  // 使用安全的方式选择动画
  if (!canJump && characterBody.velocity.y > 1 && jumpAction) {
    // 跳跃动画
    const animName = jumpAction.getClip().name;
    fadeToAction(animName, 0.2);
  } else if (isMoving && canJump && walkAction) {
    // 行走动画
    const animName = walkAction.getClip().name;
    fadeToAction(animName, 0.2);
  } else if (canJump && idleAction) {
    // 站立动画
    const animName = idleAction.getClip().name;
    fadeToAction(animName, 0.2);
  }

  // 更新相机跟随
  updateCameraFollow(deltaTime);
}

// 新增：相机跟随角色功能（完善版本）
const updateCameraFollow = (deltaTime) => {
  if (!characterBody) return;

  // 获取角色当前位置
  const characterPosition = new THREE.Vector3().copy(characterBody.position);
  
  // 使相机目标点跟随角色
  const targetPosition = new THREE.Vector3(
    characterPosition.x,
    characterPosition.y + 1.7, // 调整到角色头部或上方一点
    characterPosition.z
  );
  
  // 平滑过渡目标点
  controls.target.lerp(targetPosition, 0.1);
  
  // 更新控制器
  controls.update();
}

// 平滑切换动画的函数
const fadeToAction = (name, duration) => {
  try {
    const previousAction = currentAction
    currentAction = animationsMap.get(name)

    if (!currentAction) {
      console.warn(`Animation "${name}" not found!`);
      console.log("Available animations:", Array.from(animationsMap.keys()));
      return;
    }

    if (previousAction !== currentAction && previousAction) {
      previousAction.fadeOut(duration)
      currentAction
        .reset()
        .setEffectiveTimeScale(1)
        .setEffectiveWeight(1)
        .fadeIn(duration)
        .play()
    } else if (currentAction && !currentAction.isRunning()) {
      // 如果动画没有运行（例如第一次加载或停止后），则直接播放
      currentAction.reset().play()
    }
  } catch (error) {
    console.error(`Error in fadeToAction for animation "${name}":`, error);
  }
}

// 初始化并创建场景
const initThreeJS = () => {
  // 创建场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x87ceeb) // 天空蓝色 - 将在 createCity 中替换为天空盒

  // 初始化物理世界
  initPhysics() // 确保物理世界先初始化

  // 创建相机
  camera = new THREE.PerspectiveCamera(
    45,
    metaverseContainer.value.clientWidth / metaverseContainer.value.clientHeight,
    0.1,
    1000
  )

  // 添加光源 - 增强真实感
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
  scene.add(ambientLight)

  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
  directionalLight.position.set(-10, 20, 15)
  directionalLight.castShadow = true
  
  // 调整阴影质量
  directionalLight.shadow.camera.near = 0.1
  directionalLight.shadow.camera.far = 500
  directionalLight.shadow.camera.top = 50
  directionalLight.shadow.camera.bottom = -50
  directionalLight.shadow.camera.left = -50
  directionalLight.shadow.camera.right = 50
  directionalLight.shadow.mapSize.set(2048, 2048)
  directionalLight.shadow.bias = -0.0005
  scene.add(directionalLight)
  
  // 添加第二个方向光源
  const secondaryLight = new THREE.DirectionalLight(0xffffea, 0.4)
  secondaryLight.position.set(10, 15, -10)
  scene.add(secondaryLight)

  // 创建渲染器 - 提高渲染质量
  renderer = new THREE.WebGLRenderer({
    canvas: threeCanvas.value,
    antialias: true
  })
  renderer.setSize(metaverseContainer.value.clientWidth, metaverseContainer.value.clientHeight)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) // 限制像素比以提高性能
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFSoftShadowMap // 软阴影
  renderer.outputEncoding = THREE.sRGBEncoding // 正确的颜色输出
  renderer.toneMapping = THREE.ACESFilmicToneMapping // 电影级色调映射
  renderer.toneMappingExposure = 1.2 // 稍微提高曝光

  // 使用新函数设置控制器
  setupControls();

  // 初始化时钟
  clock = new THREE.Clock()

  // 初始化射线检测
  raycaster = new THREE.Raycaster()
  mouse = new THREE.Vector2()

  // 注册事件监听
  threeCanvas.value.addEventListener('click', onMouseClick)
  threeCanvas.value.addEventListener('mousemove', onMouseMove)

  // 创建地面 (视觉和物理)
  createGround()

  // 加载角色模型 (视觉和物理)
  loadCharacter() // 确保在物理世界之后加载

  // 异步加载汽车模型资源，加载完成后再创建城市和汽车
  loadCarModelAssets().then(() => {
    // 创建城市建筑
    createCity()
    // 添加汽车展示区
    createCarShowroom()
    // 添加多个随机位置的汽车
    populateRandomCars(20)
  }).catch(error => {
    console.error("Failed to load car model assets, proceeding without detailed cars.", error)
    // 即使汽车模型加载失败，也尝试创建城市（可能没有汽车）
    createCity()
    createCarShowroom() // 可能会创建 fallback 汽车
    populateRandomCars(20) // 可能会创建 fallback 汽车
  })

  // 处理窗口大小变化
  window.addEventListener('resize', onWindowResize)

  // 监听键盘事件 (定义处理函数以便移除)
  const handleKeyDown = (e) => {
    keysPressed[e.key.toLowerCase()] = true
    // 添加跳跃键监听
    if (e.key === ' ' && canJump) { // 按下空格键且可以跳跃
      jump()
    }
  }
  const handleKeyUp = (e) => {
    keysPressed[e.key.toLowerCase()] = false
  }
  document.addEventListener('keydown', handleKeyDown)
  document.addEventListener('keyup', handleKeyUp)

  // 开始动画循环
  animate()
}

// 创建控制器
const setupControls = () => {
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.05
  controls.minDistance = 3 // 减小最小距离，可以更近观察角色
  controls.maxDistance = 30 // 增大最大距离
  controls.maxPolarAngle = Math.PI / 2 - 0.05 // 防止相机移动到地下
  controls.rotateSpeed = 0.9 // 旋转速度
  controls.zoomSpeed = 1.2 // 缩放速度
  
  // 设置初始相机位置和方向
  camera.position.set(0, 7, 15); // 调整初始相机位置
  controls.target.set(0, 1, 0); // 初始目标点
  controls.update();
}

// 初始化物理世界
const initPhysics = () => {
  world = new CANNON.World({
    gravity: new CANNON.Vec3(0, -9.82, 0), // 设置重力
  })
  world.broadphase = new CANNON.SAPBroadphase(world) // 优化碰撞检测
  world.allowSleep = true // 允许不活动的物体休眠，提高性能

  // 创建物理材质
  const groundMaterial = new CANNON.Material('groundMaterial')
  const characterMaterial = new CANNON.Material('characterMaterial')

  // 定义地面和角色之间的接触属性 - 增加更真实的摩擦和弹性
  const groundCharacterContactMaterial = new CANNON.ContactMaterial(
    groundMaterial,
    characterMaterial,
    {
      friction: 0.3, // 增加摩擦力
      restitution: 0.2, // 增加弹性
    }
  )
  world.addContactMaterial(groundCharacterContactMaterial)

  // 创建地面物理实体
  groundBody = new CANNON.Body({
    type: CANNON.Body.STATIC, // 地面是静态的
    shape: new CANNON.Plane(),
    material: groundMaterial
  })
  groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0) // 使平面水平
  world.addBody(groundBody)

  // 创建角色物理实体 - 使用胶囊体提高真实感
  const characterHeight = 7.5
  const characterRadius = 2.5
  characterBody = new CANNON.Body({
    mass: 70,
    position: new CANNON.Vec3(0, 10, 0),
    shape: new CANNON.Sphere(characterRadius),
    material: characterMaterial,
    linearDamping: 0.1, // 降低线性阻尼使移动更灵敏
    angularDamping: 0.95,
    fixedRotation: true,
  })

  // 监听碰撞事件，用于检测是否接触地面
  characterBody.addEventListener('collide', (event) => {
    // 检查碰撞对方是否是地面
    if (event.body === groundBody || event.contact.bi === groundBody || event.contact.bj === groundBody) {
       // 检查法线方向，确保是从下方接触
       const contactNormal = new CANNON.Vec3()
       // 检查所有接触点
       event.contact.ni.negate(contactNormal) // 获取碰撞法线
       if (contactNormal.y > 0.5) { // 如果法线大致朝上，说明是下方接触
         canJump = true
       }
    }
  })

  world.addBody(characterBody)
}

// 创建更真实的地面
const createGround = () => {
  // 加载地面纹理
  const textureLoader = new THREE.TextureLoader()
  const grassTexture = textureLoader.load('https://threejs.org/examples/textures/terrain/grasslight-big.jpg')
  const roadTexture = textureLoader.load('https://threejs.org/examples/textures/floors/hardwood2_diffuse.jpg')
  
  // 设置纹理重复
  grassTexture.wrapS = THREE.RepeatWrapping
  grassTexture.wrapT = THREE.RepeatWrapping
  grassTexture.repeat.set(25, 25)
  
  roadTexture.wrapS = THREE.RepeatWrapping
  roadTexture.wrapT = THREE.RepeatWrapping
  roadTexture.repeat.set(2, 25)

  // 创建基本地面
  const groundGeometry = new THREE.PlaneGeometry(100, 100)
  const groundMaterial = new THREE.MeshStandardMaterial({
    map: grassTexture,
    roughness: 0.8,
    metalness: 0.2
  })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  ground.receiveShadow = true
  scene.add(ground)

  // 添加地面网格 (视觉辅助)
  const gridHelper = new THREE.GridHelper(100, 100, 0x000000, 0x000000)
  gridHelper.material.opacity = 0.1
  gridHelper.material.transparent = true
  scene.add(gridHelper)
}

// 创建更逼真的环境
const createCity = () => {
  // 1. 创建天空盒
  const skyboxUrls = [
    'https://threejs.org/examples/textures/cube/skybox/px.jpg',
    'https://threejs.org/examples/textures/cube/skybox/nx.jpg',
    'https://threejs.org/examples/textures/cube/skybox/py.jpg',
    'https://threejs.org/examples/textures/cube/skybox/ny.jpg',
    'https://threejs.org/examples/textures/cube/skybox/pz.jpg',
    'https://threejs.org/examples/textures/cube/skybox/nz.jpg'
  ]
  const cubeTextureLoader = new THREE.CubeTextureLoader()
  const skyboxTexture = cubeTextureLoader.load(skyboxUrls)
  scene.background = skyboxTexture
  
  // 2. 创建建筑物 - 增加真实感
  const buildings = []
  const buildingColors = [0x7d7d7d, 0x5a81b0, 0x8c8c8c, 0x697a8c]
  const textureLoader = new THREE.TextureLoader()
  const buildingTexture = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg')
  const windowTexture = textureLoader.load('https://threejs.org/examples/textures/floors/hardwood2_diffuse.jpg')
  
  // 生成随机建筑
  for (let i = 0; i < 40; i++) {
    const width = 2 + Math.random() * 4
    const height = 5 + Math.random() * 20
    const depth = 2 + Math.random() * 4
    
    const geometry = new THREE.BoxGeometry(width, height, depth)
    const material = new THREE.MeshStandardMaterial({
      color: buildingColors[Math.floor(Math.random() * buildingColors.length)],
      roughness: 0.7,
      metalness: 0.2,
      map: Math.random() > 0.5 ? buildingTexture : windowTexture
    })
    
    const building = new THREE.Mesh(geometry, material)
    
    // 随机位置，但避开中心区域
    let x, z
    do {
      x = Math.random() * 80 - 40
      z = Math.random() * 80 - 40
    } while (Math.abs(x) < 10 && Math.abs(z) < 10)
    
    building.position.set(x, height / 2, z)
    building.castShadow = true
    building.receiveShadow = true
    
    scene.add(building)
    buildings.push(building)
  }
  
  // 添加道路
  const roadGeometry = new THREE.PlaneGeometry(8, 100)
  const roadMaterial = new THREE.MeshStandardMaterial({ 
    color: 0x444444,
    roughness: 0.9,
    metalness: 0.1,
    map: textureLoader.load('https://threejs.org/examples/textures/floors/hardwood2_diffuse.jpg')
  })
  
  const roadH = new THREE.Mesh(roadGeometry, roadMaterial)
  roadH.rotation.x = -Math.PI / 2
  roadH.position.y = 0.01
  scene.add(roadH)
  
  const roadV = new THREE.Mesh(roadGeometry, roadMaterial)
  roadV.rotation.x = -Math.PI / 2
  roadV.rotation.z = Math.PI / 2
  roadV.position.y = 0.01
  scene.add(roadV)
}

// 创建汽车展示区
const createCarShowroom = () => {
  // 创建展示平台 - 放大以适应更大的车辆
  const platformGeometry = new THREE.CylinderGeometry(25, 25, 0.5, 32) // 放大平台
  const platformMaterial = new THREE.MeshStandardMaterial({
    color: 0xdddddd,
    roughness: 0.4,
    metalness: 0.3
  })
  const platform = new THREE.Mesh(platformGeometry, platformMaterial)
  platform.position.set(0, 0.25, 0)
  platform.receiveShadow = true
  scene.add(platform)
  
  // 添加展示区标志
  const signGeometry = new THREE.BoxGeometry(15, 3, 0.5) // 放大标志
  const signMaterial = new THREE.MeshStandardMaterial({
    color: 0x1e88e5,
    roughness: 0.5,
    metalness: 0.7
  })
  const sign = new THREE.Mesh(signGeometry, signMaterial)
  sign.position.set(0, 8, -20) // 调整位置
  sign.castShadow = true
  scene.add(sign)
  
  // 在展示区放置几辆特色车 - 调整间距以适应更大的车辆
  createCar(-12, 0.5, -12, Math.PI / 4)
  // createCar(12, 0.5, 12, -Math.PI / 4)
  // createCar(-12, 0.5, 12, -3 * Math.PI / 4)
  // createCar(12, 0.5, -12, 3 * Math.PI / 4)
  
  // 添加展示区灯光
  const spotLight = new THREE.SpotLight(0xffffff, 1.2) // 增加灯光强度
  spotLight.position.set(0, 25, 0) // 提高灯光位置
  spotLight.angle = Math.PI / 5
  spotLight.penumbra = 0.2
  spotLight.castShadow = true
  spotLight.shadow.mapSize.width = 2048 // 提高阴影质量
  spotLight.shadow.mapSize.height = 2048
  scene.add(spotLight)
  
  // 添加环境光反射 - 增强真实感
  const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(512) // 提高分辨率
  cubeRenderTarget.texture.type = THREE.HalfFloatType
  const pmremGenerator = new THREE.PMREMGenerator(renderer)
  pmremGenerator.compileEquirectangularShader()
  
  // 创建展示台周围的装饰物
  addShowroomDecorations()
}

// 添加展示区装饰物 - 增强场景真实感
const addShowroomDecorations = () => {
  const textureLoader = new THREE.TextureLoader()
  
  // 1. 添加装饰植物 - 放大以适应更大的角色和车辆
  for (let i = 0; i < 8; i++) {
    const angle = (i / 8) * Math.PI * 2
    const radius = 30 // 增加半径
    
    const x = Math.cos(angle) * radius
    const z = Math.sin(angle) * radius
    
    // 创建简单的树
    const trunkGeo = new THREE.CylinderGeometry(0.6, 0.8, 5, 8) // 放大树干
    const trunkMat = new THREE.MeshStandardMaterial({ 
      color: 0x8B4513,
      roughness: 0.8
    })
    const trunk = new THREE.Mesh(trunkGeo, trunkMat)
    trunk.position.set(x, 2.5, z) // 调整高度
    trunk.castShadow = true
    scene.add(trunk)
    
    // 树冠
    const leavesGeo = new THREE.SphereGeometry(3, 12, 12) // 放大树冠
    const leavesMat = new THREE.MeshStandardMaterial({ 
      color: 0x227722,
      roughness: 0.8 
    })
    const leaves = new THREE.Mesh(leavesGeo, leavesMat)
    leaves.position.set(x, 6, z) // 调整高度
    leaves.castShadow = true
    scene.add(leaves)
  }
  
  // 2. 添加灯光效果 - 调整以适应更大的场景
  for (let i = 0; i < 12; i++) {
    const angle = (i / 12) * Math.PI * 2
    const radius = 28 // 增加半径
    
    const x = Math.cos(angle) * radius
    const z = Math.sin(angle) * radius
    
    // 灯柱
    const poleGeo = new THREE.CylinderGeometry(0.2, 0.2, 5, 8) // 放大灯柱
    const poleMat = new THREE.MeshStandardMaterial({ 
      color: 0x333333,
      roughness: 0.5,
      metalness: 0.8
    })
    const pole = new THREE.Mesh(poleGeo, poleMat)
    pole.position.set(x, 2.5, z) // 调整高度
    pole.castShadow = true
    scene.add(pole)
    
    // 灯光
    const lightGeo = new THREE.SphereGeometry(0.5, 16, 16) // 放大灯光
    const lightMat = new THREE.MeshStandardMaterial({ 
      color: 0xffff99,
      roughness: 0.1,
      metalness: 0.5,
      emissive: 0xffff99,
      emissiveIntensity: 1
    })
    const lightMesh = new THREE.Mesh(lightGeo, lightMat)
    lightMesh.position.set(x, 5.5, z) // 调整高度
    scene.add(lightMesh)
    
    // 点光源
    const pointLight = new THREE.PointLight(0xffffcc, 0.6, 12) // 增加光照范围
    pointLight.position.set(x, 5.5, z) // 调整高度
    scene.add(pointLight)
  }
  
  // 3. 添加地面装饰
  const floorDecal = textureLoader.load('https://threejs.org/examples/textures/decal/decal-diffuse.png')
  const decalMat = new THREE.MeshStandardMaterial({
    map: floorDecal,
    transparent: true,
    roughness: 0.6,
    metalness: 0.4
  })
  
  const decalGeo = new THREE.CircleGeometry(25, 32) // 放大地面装饰
  const decalMesh = new THREE.Mesh(decalGeo, decalMat)
  decalMesh.rotation.x = -Math.PI / 2
  decalMesh.position.set(0, 0.02, 0) // 稍微高于地面
  scene.add(decalMesh)
}

// 异步加载汽车模型资源
const loadCarModelAssets = () => {
  return new Promise((resolve, reject) => {
    const loader = new GLTFLoader()
    // 使用本地上传的警车模型
    const carModelUrl = '/models/dodge_charger_srt_police.glb' // 使用本地模型文件
    console.log(`Loading car model from: ${carModelUrl}`)

    loader.load(carModelUrl, (gltf) => {
      carModelAsset = gltf.scene
      // 预处理模型：设置阴影、调整大小等 - 车辆变大10倍
      carModelAsset.scale.set(10.0, 10.0, 10.0) // 原来是2.0，增大5倍
      carModelAsset.traverse((node) => {
        if (node.isMesh) {
          node.castShadow = true
          node.receiveShadow = true
          
          // 提高材质质量
          if (node.material) {
            node.material = node.material.clone()
            node.material.envMapIntensity = 1.5
            node.material.needsUpdate = true
          }
        }
      })
      console.log("Car model asset loaded successfully.")
      resolve() // 加载成功
    }, 
    // 添加加载进度回调以方便调试
    (xhr) => {
      const percentComplete = (xhr.loaded / xhr.total) * 100;
      console.log(`Loading model: ${Math.round(percentComplete)}% completed`);
    },
    (error) => {
      console.error(`Failed to load car model from ${carModelUrl}:`, error)
      carModelAsset = null // 确保失败时 asset 为 null
      reject(error) // 加载失败
    })
  })
}

// 创建汽车模型 (使用克隆)
const createCar = (x, y, z, rotation) => {
  if (!carModelAsset) {
    console.warn("Car model asset not loaded, creating fallback box.")
    // 如果模型未加载，创建一个简单的方块作为 fallback
    const fallbackGeo = new THREE.BoxGeometry(2, 1, 4)
    const fallbackMat = new THREE.MeshStandardMaterial({ color: 0xcccccc })
    const fallbackCar = new THREE.Mesh(fallbackGeo, fallbackMat)
    fallbackCar.position.set(x, y + 0.5, z) // 调整位置
    fallbackCar.rotation.y = rotation
    fallbackCar.castShadow = true
    fallbackCar.receiveShadow = true
    fallbackCar.userData.type = 'car' // 标记类型
    fallbackCar.userData.name = '占位车辆' // 更新名称
    fallbackCar.userData.info = { name: '占位车辆', price: '未知', age: '未知', mileage: '未知', engine: '未知', description: '车辆模型加载失败，显示占位符。' } // 更新信息
    scene.add(fallbackCar)
    cars.push(fallbackCar)
    return fallbackCar
  }

  // 克隆预加载的模型
  const car = carModelAsset.clone()
  car.userData.type = 'car' // 标记为汽车对象

  // 随机生成车辆信息 (更新以匹配警车或更通用)
  const carBrands = ['警用道奇', '警用特种车', '重型巡逻车'] // 更新品牌
  const carModels = ['Charger SRT', '警用特勤版', '高速巡逻版'] // 更新型号
  const years = ['2020款', '2021款', '2022款', '2023款']
  const prices = ['￥380,000', '￥420,000', '￥450,000', '￥480,000'] // 更新价格范围
  const ages = ['1年', '2年', '3年']
  const mileages = ['10,000公里', '20,000公里', '30,000公里']
  const engines = ['6.4L V8', '5.7L HEMI', '高性能引擎'] // 更新引擎类型

  const brand = carBrands[Math.floor(Math.random() * carBrands.length)]
  const model = carModels[Math.floor(Math.random() * carModels.length)]
  const year = years[Math.floor(Math.random() * years.length)]

  car.userData.name = `${brand} ${model} ${year}`
  car.userData.info = {
    name: car.userData.name,
    price: prices[Math.floor(Math.random() * prices.length)],
    age: ages[Math.floor(Math.random() * ages.length)],
    mileage: mileages[Math.floor(Math.random() * mileages.length)],
    engine: engines[Math.floor(Math.random() * engines.length)],
    description: `这款${brand}${model}车况极佳，曾服务于精英警队，拥有顶尖性能和可靠性。${engines[Math.floor(Math.random() * engines.length)]}发动机，完美融合强大动力与灵活操控。` // 更新描述
  }

  // 定位汽车
  car.position.set(x, y, z)
  car.rotation.y = rotation
  scene.add(car)
  cars.push(car) // 将车辆添加到数组中
  
  return car
}

// 新增：用于分散创建随机汽车的函数
const populateRandomCars = (count) => {
  // 创建一组道路坐标点，沿着道路放置汽车 - 调整间距以适应更大的汽车
  const roadPositions = [
    // 横向道路上的点
    ...Array(10).fill().map((_, i) => ({ x: -40 + i*15, z: 0, rotation: Math.PI/2 })), // 增加间距
    ...Array(10).fill().map((_, i) => ({ x: -40 + i*15, z: 0, rotation: -Math.PI/2 })),
    
    // 纵向道路上的点
    ...Array(10).fill().map((_, i) => ({ x: 0, z: -40 + i*15, rotation: 0 })), // 增加间距
    ...Array(10).fill().map((_, i) => ({ x: 0, z: -40 + i*15, rotation: Math.PI })),
  ];
  
  // 使用道路坐标创建汽车
  for (let i = 0; i < 1; i++) {
    const pos = roadPositions[i];
    // 在道路上随机放置车辆，小幅度随机偏移
    const offsetX = (Math.random() - 0.5) * 3; // 增加偏移量
    createCar(pos.x + offsetX, 0, pos.z, pos.rotation);
  }
  
  // 如果需要更多车辆，则随机放置在场景中
  for (let i = roadPositions.length; i < count; i++) {
    const x = Math.random() * 80 - 40;
    const z = Math.random() * 80 - 40;
    createCar(x, 0, z, Math.random() * Math.PI * 2);
  }
}

// 加载角色 (视觉 - GLTF模型)
const loadCharacter = () => {
  const loader = new GLTFLoader()
  // 使用更现代的角色模型
  loader.load('https://threejs.org/examples/models/gltf/Soldier.glb', (gltf) => {
    character = gltf.scene
    character.scale.set(2.5, 2.5, 2.5) // 原来是0.5，增大5倍
    
    // 先旋转模型180度，使其面向正确方向
    character.rotation.y = Math.PI;
    
    character.traverse((node) => {
      if (node.isMesh) {
        node.castShadow = true
        node.receiveShadow = true // 模型部分也可以接收阴影
      }
    })
    scene.add(character)

    // 初始化动画混合器
    mixer = new THREE.AnimationMixer(character)
    animationsMap = new Map()
    
    // 打印所有可用动画名称以便调试
    console.log("Available animations in model:");
    gltf.animations.forEach((clip) => {
      console.log(`- ${clip.name}`);
      animationsMap.set(clip.name, mixer.clipAction(clip))
    })

    // 设置初始动画 - 测试不同的动画名称
    const idleAnimationNames = ['Idle', 'idle', 'IDLE', 'Idle_Anim'];
    let foundIdle = false;
    
    for (const idleName of idleAnimationNames) {
      currentAction = animationsMap.get(idleName);
      if (currentAction) {
        console.log(`Found idle animation: ${idleName}`);
        currentAction.play();
        foundIdle = true;
        break;
      }
    }
    
    if (!foundIdle) {
      console.warn("No idle animation found, trying first available animation");
      if (gltf.animations.length > 0) {
        const firstAnimName = gltf.animations[0].name;
        currentAction = animationsMap.get(firstAnimName);
        console.log(`Using first animation: ${firstAnimName}`);
        currentAction.play();
      } else {
        console.error("No animations found in the model!");
      }
    }

    // 创建角色控制器 (引用加载的模型)
    characterControls = {
      model: character,
      speed: 12, // 因为角色变大了，相应增加移动速度
      rotationSpeed: 0.15,
      direction: new THREE.Vector3()
    }

    // 完成加载
    loading.value = false

  }, undefined, (error) => {
    console.error('加载角色模型失败:', error)
    // 加载失败，可以回退到使用胶囊体或显示错误信息
    loadFallbackCharacter() // 调用备用加载函数
    loading.value = false
  })
}

// 加载失败时的备用角色 (之前的胶囊体)
const loadFallbackCharacter = () => {
   console.warn("Loading fallback character (Capsule)")
   const characterGeometry = new THREE.CapsuleGeometry(2.5, 5.0, 4, 8) // 胶囊体尺寸也增大5倍
   const characterMaterial = new THREE.MeshStandardMaterial({
     color: 0xff6600,
     roughness: 0.5,
     metalness: 0.1
   })
   character = new THREE.Mesh(characterGeometry, characterMaterial)
   character.castShadow = true
   
   // 旋转胶囊角色，保持一致性
   character.rotation.y = Math.PI;
   
   scene.add(character)

   characterControls = {
     model: character,
     speed: 12, // 增加速度
     rotationSpeed: 0.15,
     direction: new THREE.Vector3()
   }
}

// 跳跃函数 - 增强跳跃体验
const jump = () => {
  if (canJump && characterBody) {
    characterBody.velocity.y = jumpVelocity * 1.5; // 增加跳跃高度以匹配更大的角色
    canJump = false // 跳跃后暂时不能再跳
    
    // 播放跳跃动画
    const jumpAction = animationsMap.get('Jump') || animationsMap.get('jump')
    if (jumpAction) {
      fadeToAction(jumpAction.getClip().name, 0.1)
    }
  }
}

// 处理窗口大小变化
const onWindowResize = () => {
  camera.aspect = metaverseContainer.value.clientWidth / metaverseContainer.value.clientHeight
  camera.updateProjectionMatrix()
  renderer.setSize(metaverseContainer.value.clientWidth, metaverseContainer.value.clientHeight)
}

// 动画循环
const animate = () => {
  requestAnimationFrame(animate)

  const deltaTime = clock.getDelta()
  const dt = Math.min(deltaTime, 0.1) // 防止deltaTime过大导致物理计算错误

  // 1. 更新物理世界
  if (world) {
    world.step(timeStep, dt, 3) // 使用修正后的 dt
  }

  // 2. 更新角色视觉位置和姿态 (基于物理实体)
  if (character && characterBody) {
    character.position.copy(characterBody.position)
    // 根据soldier模型，可能不需要下移调整，或者需要不同的偏移量
    character.position.y += 0; // 根据模型调整高度，可能需要正向或负向偏移
  }

  // 3. 更新动画混合器
  if (mixer) {
    mixer.update(dt) // 使用修正后的 dt
  }

  // 4. 更新角色控制器逻辑 (移动、动画状态等)
  updateCharacter(dt) // 会内部调用 updateCameraFollow

  // 5. 更新射线检测 (用于交互)
  updateRaycaster()

  // 6. 更新相机控制器
  controls.update()

  // 7. 渲染场景
  renderer.render(scene, camera)
}

// 返回首页
const goBack = () => {
  router.push('/')
}

// 组件挂载时
onMounted(() => {
  // 延迟初始化，确保DOM已渲染
  setTimeout(() => {
    try {
      initThreeJS()
    } catch (error) {
      console.error('初始化3D场景失败:', error)
      loading.value = false
    }
  }, 100)
})

// 组件卸载前清理
onBeforeUnmount(() => {
  if (renderer) {
    renderer.dispose()
  }
  
  // 移除事件监听 (需要重新定义函数来移除，或者将函数提升到外部作用域)
  window.removeEventListener('resize', onWindowResize)
  // 定义与添加时相同的处理函数用于移除
  const handleKeyDownToRemove = (e) => {
    keysPressed[e.key.toLowerCase()] = true
    if (e.key === ' ' && canJump) { jump() }
  }
  const handleKeyUpToRemove = (e) => {
    keysPressed[e.key.toLowerCase()] = false
  }
  document.removeEventListener('keydown', handleKeyDownToRemove)
  document.removeEventListener('keyup', handleKeyUpToRemove)
  
  if (threeCanvas.value) {
    threeCanvas.value.removeEventListener('click', onMouseClick)
    threeCanvas.value.removeEventListener('mousemove', onMouseMove)
  }
})
</script>

<style scoped>
.metaverse-page {
  min-height: 100vh;
  background-color: #f5f7fa;
  display: flex;
  flex-direction: column;
}

.page-header {
  background-color: #fff;
  padding: 20px;
  text-align: center;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.page-header .title {
  font-size: 32px;
  color: #303133;
  margin: 0 0 10px 0;
}

.page-header .subtitle {
  font-size: 16px;
  color: #606266;
  margin: 0;
}

.metaverse-container {
  flex: 1;
  position: relative;
  height: calc(100vh - 200px);
  min-height: 500px;
  width: 100%;
}

.three-canvas {
  width: 100%;
  height: 100%;
  display: block;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.8);
  z-index: 10;
}

.icon-container {
  margin-bottom: 20px;
}

.icon-container i {
  font-size: 60px;
  color: #409EFF;
  animation: spin 2s linear infinite;
}

.controls-info {
  position: absolute;
  top: 20px;
  left: 20px;
  background-color: rgba(0, 0, 0, 0.6);
  color: white;
  padding: 10px 15px;
  border-radius: 5px;
  z-index: 2;
}

.controls-info ul {
  margin: 5px 0 0 0;
  padding-left: 20px;
}

.controls-info li {
  margin-bottom: 5px;
  font-size: 14px;
}

.return-home {
  padding: 20px;
  text-align: center;
}

/* 车辆信息面板 */
.car-info-panel {
  position: absolute;
  right: 20px;
  top: 20px;
  width: 300px;
  background-color: white;
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 3;
  overflow: hidden;
}

.car-info-header {
  background-color: #409EFF;
  color: white;
  padding: 12px 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.car-info-header h3 {
  margin: 0;
  font-size: 16px;
}

.close-btn {
  cursor: pointer;
  font-size: 20px;
}

.car-info-body {
  padding: 15px;
}

.car-specs {
  margin-bottom: 15px;
}

.spec-item {
  display: flex;
  margin-bottom: 8px;
}

.spec-item .label {
  width: 60px;
  color: #606266;
}

.spec-item .value {
  font-weight: bold;
  color: #303133;
}

.car-description {
  margin-bottom: 15px;
  color: #606266;
  font-size: 14px;
}

.car-actions {
  display: flex;
  justify-content: space-between;
}

/* 交互提示 */
.interaction-tooltip {
  position: absolute;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 14px;
  pointer-events: none;
  z-index: 2;
  transform: translate(-50%, -100%);
}

/* 小地图 */
.mini-map {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 150px;
  height: 150px;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 5px;
  overflow: hidden;
  z-index: 2;
  border: 2px solid rgba(255, 255, 255, 0.3);
}

.map-container {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: #3a7e4f;
}

.player-marker {
  position: absolute;
  width: 10px;
  height: 15px;
  background-color: #ff6600;
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  transform-origin: center;
}

/* 数字人功能 */
.digital-human-feature {
  position: absolute;
  top: 50%;
  right: 20px;
  width: 200px;
  transform: translateY(-50%);
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  padding: 15px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.feature-icon {
  width: 50px;
  height: 50px;
  background-color: #409EFF;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 15px;
}

.feature-icon i {
  font-size: 30px;
  color: white;
}

.feature-content h3 {
  margin: 0 0 10px 0;
  color: #303133;
}

.feature-content p {
  margin: 0 0 15px 0;
  color: #606266;
  font-size: 14px;
}

.development-badge {
  background-color: #E6A23C;
  color: white;
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 12px;
  display: inline-block;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

</style>